package com.xbongbong.sys.help;

import com.alibaba.fastjson.JSON;
import com.xbongbong.i18n.util.I18nMessageUtil;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.pojo.AppPermissionPojo;
import com.xbongbong.paas.toolbox.pojo.ModulePermissionPojo;
import com.xbongbong.paas.toolbox.pojo.PermissionTermsPojo;
import com.xbongbong.paas.toolbox.wrap.UserVO;
import com.xbongbong.pro.constant.CommonConstant;
import com.xbongbong.pro.enums.SaasMarkEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.enums.permission.enums.AddProPermissionAliasEnum;
import com.xbongbong.pro.enums.permission.enums.DeleteProPermissionAliasEnum;
import com.xbongbong.pro.enums.permission.enums.FileCabinetDeletePermissionEnum;
import com.xbongbong.pro.enums.permission.enums.FileCabinetVisiblePermissionEnum;
import com.xbongbong.pro.enums.permission.enums.PrintProPermissionAliasEnum;
import com.xbongbong.pro.enums.permission.enums.UpdateProPermissionAliasEnum;
import com.xbongbong.pro.enums.permission.enums.ViewProPermissionAliasEnum;
import com.xbongbong.pro.permission.pojo.dto.VerifyAddPermissionDTO;
import com.xbongbong.pro.permission.pojo.dto.VerifyDeletePermissionDTO;
import com.xbongbong.pro.permission.pojo.dto.VerifyUpdatePermissionDTO;
import com.xbongbong.pro.permission.pojo.dto.VerifyViewPermissionDTO;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;

/**
 * @author 吴峰 & kaka
 * @version v1.0
 * @date 2019/4/24 9:35
 * @since v1.0
 */
@Component
@Slf4j
public class ProPermissionHelp {

    private static final Logger LOG = LoggerFactory.getLogger(ProPermissionHelp.class);

    /**
     * 校验删除权限
     *
     * @param verifyDeletePermissionDTO 校验权限所需参数
     * @throws XbbException 业务异常
     */
    public static void verifyDeletePermission(VerifyDeletePermissionDTO verifyDeletePermissionDTO) throws XbbException {
        Integer saasMark = verifyDeletePermissionDTO.getSaasMark();
        UserVO userVO = verifyDeletePermissionDTO.getLoginUser();

        if (Objects.equals(SaasMarkEnum.SAAS.getCode(), saasMark)) {
            Integer businessType = verifyDeletePermissionDTO.getBusinessType();
            DeleteProPermissionAliasEnum deleteProPermissionAliasEnum = DeleteProPermissionAliasEnum.getByCode(businessType);
            if (Objects.nonNull(deleteProPermissionAliasEnum)) {
                if (!userVO.getPermSet().contains(deleteProPermissionAliasEnum.getAlias())) {
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100050, String.format(SystemErrorCodeEnum.API_ERROR_100050.getMsg(), deleteProPermissionAliasEnum.getMemo()));
                }
            }
        } else {
            Set<Long> idSet = getPaasDeleteMenuIdSet(userVO.getPaasPermissions());
            if (!userVO.isAdminOrBoss() && !idSet.contains(verifyDeletePermissionDTO.getMenuId())) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100050, SystemErrorCodeEnum.API_ERROR_100050.getMsg(), I18nMessageUtil.getMessage(CommonConstant.DEL));
            }
        }

    }

    /**
     * 校验新建权限
     *
     * @param userVO          校验权限所需参数
     * @param distributorMark
     * @param menuId
     * @param saasMark
     * @param businessType
     * @return true: 有权限；false：无权限
     * @throws XbbException 业务异常
     */
    public static boolean verifyViewPermission(UserVO userVO, Integer saasMark, Integer businessType, Long menuId, Integer distributorMark) throws XbbException {

        if (Objects.equals(SaasMarkEnum.SAAS.getCode(), saasMark)) {
            ViewProPermissionAliasEnum addProPermissionAliasEnum = ViewProPermissionAliasEnum.getByCode(XbbRefTypeEnum.transferBusinessType4Distributor(businessType, distributorMark));
            return userVO.isAdminOrBoss() || userVO.getPermSet().contains(addProPermissionAliasEnum.getAlias());
        } else {
            Set<Long> idSet = getPaasCreateMenuIdSet(userVO.getPaasPermissions());
            return userVO.isAdminOrBoss() || idSet.contains(menuId);
        }

    }

    /**
     * 校验新建权限(没有权限抛异常)
     *
     * @param verifyAddPermissionDTO 校验权限所需参数
     * @throws XbbException 业务异常
     */
    public static void verifyAddPermission(VerifyAddPermissionDTO verifyAddPermissionDTO) throws XbbException {
        Integer saasMark = verifyAddPermissionDTO.getSaasMark();
        UserVO userVO = verifyAddPermissionDTO.getLoginUser();

        if (Objects.equals(SaasMarkEnum.SAAS.getCode(), saasMark)) {
            Integer businessType = verifyAddPermissionDTO.getBusinessType();
            AddProPermissionAliasEnum addProPermissionAliasEnum = AddProPermissionAliasEnum.getByCode(XbbRefTypeEnum.transferBusinessType4Distributor(businessType, verifyAddPermissionDTO.getDistributorMark()));
            if (Objects.nonNull(addProPermissionAliasEnum)) {
                if (!userVO.getPermSet().contains(addProPermissionAliasEnum.getAlias())) {
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100050, String.format(SystemErrorCodeEnum.API_ERROR_100050.getMsg(), addProPermissionAliasEnum.getMemo()));
                }
            }
        } else {
            Set<Long> idSet = getPaasCreateMenuIdSet(userVO.getPaasPermissions());
            if (!userVO.isAdminOrBoss() && !idSet.contains(verifyAddPermissionDTO.getMenuId())) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100050, SystemErrorCodeEnum.API_ERROR_100050.getMsg(), I18nMessageUtil.getMessage(CommonConstant.ADD));
            }
        }

    }

    /**
     * 校验新建权限(没有权限返回false)
     *
     * @param verifyAddPermissionDTO
     * @return
     * @throws XbbException
     */
    public static Boolean getAddPermission(VerifyAddPermissionDTO verifyAddPermissionDTO) throws XbbException {
        Integer saasMark = verifyAddPermissionDTO.getSaasMark();
        UserVO userVO = verifyAddPermissionDTO.getLoginUser();

        if (Objects.equals(SaasMarkEnum.SAAS.getCode(), saasMark)) {
            Integer businessType = verifyAddPermissionDTO.getBusinessType();
            AddProPermissionAliasEnum addProPermissionAliasEnum = AddProPermissionAliasEnum.getByCode(businessType);
            if (Objects.nonNull(addProPermissionAliasEnum)) {
                if (!userVO.getPermSet().contains(addProPermissionAliasEnum.getAlias())) {
                    return false;
                }
            }
        } else {
            Set<Long> idSet = getPaasCreateMenuIdSet(userVO.getPaasPermissions());
            if (!userVO.isAdminOrBoss() && !idSet.contains(verifyAddPermissionDTO.getMenuId())) {
                return false;
            }
        }
        return true;
    }

    /**
     * 校验编辑权限(没有权限抛异常)
     *
     * @param verifyUpdatePermissionDTO 校验权限所需参数
     * @throws XbbException 业务异常
     */
    public static void verifyEditPermission(VerifyUpdatePermissionDTO verifyUpdatePermissionDTO) throws XbbException {
        Integer saasMark = verifyUpdatePermissionDTO.getSaasMark();
        UserVO userVO = verifyUpdatePermissionDTO.getLoginUser();

        if (Objects.equals(SaasMarkEnum.SAAS.getCode(), saasMark)) {
            Integer businessType = verifyUpdatePermissionDTO.getBusinessType();
            businessType = XbbRefTypeEnum.transferBusinessType4Distributor(businessType, verifyUpdatePermissionDTO.getDistributorMark());
            UpdateProPermissionAliasEnum updateProPermissionAliasEnum = UpdateProPermissionAliasEnum.getByCode(businessType);
            if (Objects.nonNull(updateProPermissionAliasEnum)) {
                if (!userVO.getPermSet().contains(updateProPermissionAliasEnum.getAlias())) {
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100050, String.format(SystemErrorCodeEnum.API_ERROR_100050.getMsg(), updateProPermissionAliasEnum.getMemo()));
                }
            }
        } else {
            Set<Long> idSet = getPaasEditMenuIdSet(userVO.getPaasPermissions());
            if (!userVO.isAdminOrBoss() && !idSet.contains(verifyUpdatePermissionDTO.getMenuId())) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100050, SystemErrorCodeEnum.API_ERROR_100050.getMsg(), I18nMessageUtil.getMessage(CommonConstant.EDIT));
            }
        }
    }

    /**
     * 校验编辑权限(没有权限返回false)
     *
     * @param verifyUpdatePermissionDTO 校验权限所需参数
     * @throws XbbException 业务异常
     */
    public static boolean getEditPermission(VerifyUpdatePermissionDTO verifyUpdatePermissionDTO) throws XbbException {
        Integer saasMark = verifyUpdatePermissionDTO.getSaasMark();
        UserVO userVO = verifyUpdatePermissionDTO.getLoginUser();

        if (Objects.equals(SaasMarkEnum.SAAS.getCode(), saasMark)) {
            Integer businessType = verifyUpdatePermissionDTO.getBusinessType();
            businessType = XbbRefTypeEnum.transferBusinessType4Distributor(businessType, verifyUpdatePermissionDTO.getDistributorMark());
            UpdateProPermissionAliasEnum updateProPermissionAliasEnum = UpdateProPermissionAliasEnum.getByCode(businessType);
            if (Objects.nonNull(updateProPermissionAliasEnum)) {
                return userVO.getPermSet().contains(updateProPermissionAliasEnum.getAlias());
            }
        } else {
            Set<Long> idSet = getPaasEditMenuIdSet(userVO.getPaasPermissions());
            return userVO.isAdminOrBoss() || idSet.contains(verifyUpdatePermissionDTO.getMenuId());
        }
        return true;
    }

    /**
     * 校验查看权限
     *
     * @param verifyViewPermissionDTO 校验权限所需参数
     * @throws XbbException 业务异常
     */
    public static void verifyQueryPermission(VerifyViewPermissionDTO verifyViewPermissionDTO) throws XbbException {
        Integer saasMark = verifyViewPermissionDTO.getSaasMark();
        UserVO userVO = verifyViewPermissionDTO.getLoginUser();

        if (Objects.equals(SaasMarkEnum.SAAS.getCode(), saasMark)) {
            Integer businessType = verifyViewPermissionDTO.getBusinessType();
            ViewProPermissionAliasEnum viewProPermissionAliasEnum = ViewProPermissionAliasEnum.getByCode(businessType);
            if (Objects.nonNull(viewProPermissionAliasEnum)) {
                if (!userVO.getPermSet().contains(viewProPermissionAliasEnum.getAlias())) {
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100050, String.format(SystemErrorCodeEnum.API_ERROR_100050.getMsg(), viewProPermissionAliasEnum.getMemo()));
                }
            }
        } else {
            Set<Long> idSet = getPaasViewMenuIdSet(userVO.getPaasPermissions());
            if (!userVO.isAdminOrBoss() && !idSet.contains(verifyViewPermissionDTO.getMenuId())) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100050, SystemErrorCodeEnum.API_ERROR_100050.getMsg(), I18nMessageUtil.getMessage(CommonConstant.VIEW));
            }
        }
    }

    public static void verifyPermission(UserVO userVO, String permissionAlias) throws XbbException {
        if (!userVO.isAdminOrBoss() && !hasThisPermission(userVO, permissionAlias)) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100017);
        }
    }

    /**
     * 校验文件柜可见权限
     *
     * @param verifyViewPermissionDTO 校验权限所需参数
     * @throws XbbException 业务异常
     */
    public static boolean verifyFileVisiblePermission(VerifyViewPermissionDTO verifyViewPermissionDTO) throws XbbException {
        Integer saasMark = verifyViewPermissionDTO.getSaasMark();
        UserVO userVO = verifyViewPermissionDTO.getLoginUser();
        boolean canSee = true;
        if (Objects.equals(SaasMarkEnum.SAAS.getCode(), saasMark)) {
            Integer businessType = verifyViewPermissionDTO.getBusinessType();
            FileCabinetVisiblePermissionEnum viewProPermissionAliasEnum = FileCabinetVisiblePermissionEnum.getByCode(businessType);
            if (Objects.nonNull(viewProPermissionAliasEnum)) {
                if (!userVO.getPermSet().contains(viewProPermissionAliasEnum.getAlias())) {
                    canSee = false;
                }
            }
        } else {
            Set<Long> idSet = getPaasFileVisibleMenuIdSet(userVO.getPaasPermissions());
            if (!userVO.isAdminOrBoss() && !idSet.contains(verifyViewPermissionDTO.getMenuId())) {
                canSee = false;
            }
        }
        return canSee;
    }

    /**
     * 校验文件柜可见权限
     *
     * @param verifyViewPermissionDTO 校验权限所需参数
     * @throws XbbException 业务异常
     */
    public static boolean verifyFileDeletePermission(VerifyViewPermissionDTO verifyViewPermissionDTO) throws XbbException {
        Integer saasMark = verifyViewPermissionDTO.getSaasMark();
        UserVO userVO = verifyViewPermissionDTO.getLoginUser();
        boolean canDelete = true;
        if (Objects.equals(SaasMarkEnum.SAAS.getCode(), saasMark)) {
            Integer businessType = verifyViewPermissionDTO.getBusinessType();
            FileCabinetDeletePermissionEnum viewProPermissionAliasEnum = FileCabinetDeletePermissionEnum.getByCode(businessType);
            if (Objects.nonNull(viewProPermissionAliasEnum)) {
                if (!userVO.getPermSet().contains(viewProPermissionAliasEnum.getAlias())) {
                    canDelete = false;
                }
            }
        } else {
            Set<Long> idSet = getPaasFileDeleteMenuIdSet(userVO.getPaasPermissions());
            if (!userVO.isAdminOrBoss() && !idSet.contains(verifyViewPermissionDTO.getMenuId())) {
                canDelete = false;
            }
        }
        return canDelete;
    }

    /**
     * 获取详情页的打印权限
     *
     * @param businessType 业务类型
     * @param userVO       权限
     */
    public static boolean hasPrintPermission(Integer businessType, UserVO userVO) {
        PrintProPermissionAliasEnum proPermissionAliasEnum = PrintProPermissionAliasEnum.getByCode(businessType);
        if (Objects.isNull(proPermissionAliasEnum)) {
            return false;
        }
        return hasThisPermission(userVO, proPermissionAliasEnum.getAlias());
    }

    /**
     * 校验编辑权限
     *
     * @param permissionAlias 校验权限所需参数
     */
    public static Boolean hasThisPermission(UserVO userVO, String permissionAlias) {
        Boolean has = false;
        Set<String> permSet = userVO.getPermSet();
        if (permSet == null) {
            return false;
        }
        if (permSet.contains(permissionAlias)) {
            has = true;
        }
        return has;
    }

    /**
     * 校验编辑权限
     *
     * @param permissionAlias 校验权限所需参数
     */
    public static Boolean hasPermission(UserVO userVO, String permissionAlias) {
        boolean has = false;
        Set<String> permSet = userVO.getPermSet();
        if (permSet == null) {
            return false;
        }
        if (userVO.isAdminOrBoss() || permSet.contains(permissionAlias)) {
            has = true;
        }
        return has;
    }

    /**
     * paas权限取并集，取 permissions1 和 permissions2 的并集
     * 结构为数据库存储结构
     *
     * @param permissions1 paas权限1
     * @param permissions2 paas权限2
     * @return permissions1 和 permissions2 的paas权限并集，转为字符串
     */
    public static String paasPermissionUnion(String permissions1, String permissions2) {
        return SysProPermissionHelp.paasPermissionUnion(permissions1, permissions2);
    }

    /**
     * 根据paas权限计算该用户可以新建的paas菜单id集合
     *
     * @param paasPermissionsStr 该用户具有的paas权限
     * @return 该用户可以看到的paas菜单id集合
     */
    public static Set<Long> getPaasCreateMenuIdSet(String paasPermissionsStr) {
        Set<Long> paasMenuPerm = new HashSet<>();
        List<AppPermissionPojo> appPerms;
        try {
            appPerms = JSON.parseArray(paasPermissionsStr, AppPermissionPojo.class);
        } catch (Exception e) {
            LOG.error("checkPermission paasPermissions数据不规范" + paasPermissionsStr, e);
            appPerms = new ArrayList<>();
        }
        if (appPerms != null) {
            for (AppPermissionPojo appPerm : appPerms) {
                List<ModulePermissionPojo> modules = appPerm.getModules();
                if (modules != null && !modules.isEmpty()) {
                    for (ModulePermissionPojo modulePerm : modules) {
                        // 有查看权限
                        if (modulePerm.getPermission().getCreate().equals(1)) {
                            paasMenuPerm.add(modulePerm.getId());
                        }
                    }
                }
            }
        }
        return paasMenuPerm;
    }

    /**
     * 根据paas权限计算该用户可以编辑的paas菜单id集合
     *
     * @param paasPermissionsStr 该用户具有的paas权限
     * @return 该用户可以看到的paas菜单id集合
     */
    public static Set<Long> getPaasDeleteMenuIdSet(String paasPermissionsStr) {
        Set<Long> paasMenuPerm = new HashSet<>();
        List<AppPermissionPojo> appPerms;
        try {
            appPerms = JSON.parseArray(paasPermissionsStr, AppPermissionPojo.class);
        } catch (Exception e) {
            LOG.error("checkPermission paasPermissions数据不规范" + paasPermissionsStr, e);
            appPerms = new ArrayList<>();
        }
        if (appPerms != null) {
            for (AppPermissionPojo appPerm : appPerms) {
                List<ModulePermissionPojo> modules = appPerm.getModules();
                if (modules != null && !modules.isEmpty()) {
                    for (ModulePermissionPojo modulePerm : modules) {
                        // 有查看权限
                        if (modulePerm.getPermission().getDelete().equals(1)) {
                            paasMenuPerm.add(modulePerm.getId());
                        }
                    }
                }
            }
        }
        return paasMenuPerm;
    }

    /**
     * 根据paas权限计算该用户可以编辑的paas菜单id集合
     *
     * @param paasPermissionsStr 该用户具有的paas权限
     * @return 该用户可以看到的paas菜单id集合
     */
    public static Set<Long> getPaasEditMenuIdSet(String paasPermissionsStr) {
        Set<Long> paasMenuPerm = new HashSet<>();
        List<AppPermissionPojo> appPerms;
        try {
            appPerms = JSON.parseArray(paasPermissionsStr, AppPermissionPojo.class);
        } catch (Exception e) {
            LOG.error("checkPermission paasPermissions数据不规范" + paasPermissionsStr, e);
            appPerms = new ArrayList<>();
        }
        if (appPerms != null) {
            for (AppPermissionPojo appPerm : appPerms) {
                List<ModulePermissionPojo> modules = appPerm.getModules();
                if (modules != null && !modules.isEmpty()) {
                    for (ModulePermissionPojo modulePerm : modules) {
                        // 有查看权限
                        if (modulePerm.getPermission().getUpdate().equals(1)) {
                            paasMenuPerm.add(modulePerm.getId());
                        }
                    }
                }
            }
        }
        return paasMenuPerm;
    }

    /**
     * 根据paas权限计算该用户可以查看文件柜的paas菜单id集合
     *
     * @param paasPermissionsStr 该用户具有的paas权限
     * @return 该用户可以看到的paas菜单id集合
     */
    public static Set<Long> getPaasFileVisibleMenuIdSet(String paasPermissionsStr) {
        Set<Long> paasMenuPerm = new HashSet<>();
        List<AppPermissionPojo> appPerms;
        try {
            appPerms = JSON.parseArray(paasPermissionsStr, AppPermissionPojo.class);
        } catch (Exception e) {
            LOG.error("checkPermission paasPermissions数据不规范" + paasPermissionsStr, e);
            appPerms = new ArrayList<>();
        }
        if (appPerms != null) {
            for (AppPermissionPojo appPerm : appPerms) {
                List<ModulePermissionPojo> modules = appPerm.getModules();
                if (modules != null && !modules.isEmpty()) {
                    for (ModulePermissionPojo modulePerm : modules) {
                        // 有查看权限
                        if (modulePerm.getPermission().getFileCabinetVisible().equals(1)) {
                            paasMenuPerm.add(modulePerm.getId());
                        }
                    }
                }
            }
        }
        return paasMenuPerm;
    }

    /**
     * 根据paas权限计算该用户可以删除文件的paas菜单id集合
     *
     * @param paasPermissionsStr 该用户具有的paas权限
     * @return 该用户可以看到的paas菜单id集合
     */
    public static Set<Long> getPaasFileDeleteMenuIdSet(String paasPermissionsStr) {
        Set<Long> paasMenuPerm = new HashSet<>();
        List<AppPermissionPojo> appPerms;
        try {
            appPerms = JSON.parseArray(paasPermissionsStr, AppPermissionPojo.class);
        } catch (Exception e) {
            LOG.error("checkPermission paasPermissions数据不规范" + paasPermissionsStr, e);
            appPerms = new ArrayList<>();
        }
        if (appPerms != null) {
            for (AppPermissionPojo appPerm : appPerms) {
                List<ModulePermissionPojo> modules = appPerm.getModules();
                if (modules != null && !modules.isEmpty()) {
                    for (ModulePermissionPojo modulePerm : modules) {
                        // 有查看权限
                        if (modulePerm.getPermission().getFileCabinetDelete().equals(1)) {
                            paasMenuPerm.add(modulePerm.getId());
                        }
                    }
                }
            }
        }
        return paasMenuPerm;
    }

    /**
     * 根据paas权限计算该用户可以看到的paas菜单id集合
     *
     * @param paasPermissionsStr 该用户具有的paas权限
     * @return 该用户可以看到的paas菜单id集合
     */
    public static Set<Long> getPaasViewMenuIdSet(String paasPermissionsStr) {
        Set<Long> paasMenuPerm = new HashSet<>();
        List<AppPermissionPojo> appPerms;
        try {
            appPerms = JSON.parseArray(paasPermissionsStr, AppPermissionPojo.class);
        } catch (Exception e) {
            LOG.error("checkPermission paasPermissions数据不规范" + paasPermissionsStr, e);
            appPerms = new ArrayList<>();
        }
        if (appPerms != null) {
            for (AppPermissionPojo appPerm : appPerms) {
                List<ModulePermissionPojo> modules = appPerm.getModules();
                if (modules != null && !modules.isEmpty()) {
                    for (ModulePermissionPojo modulePerm : modules) {
                        // 有查看权限
                        if (modulePerm.getPermission().getRead().equals(1)) {
                            paasMenuPerm.add(modulePerm.getId());
                        }
                    }
                }
            }
        }
        return paasMenuPerm;
    }

    /**
     * 根据paas权限计算该用户可以看到的paas应用id集合
     *
     * @param paasPermissionsStr 该用户具有的paas权限
     * @return 该用户可以看到的paas应用id集合
     */
    public static Set<Long> getPaasViewAppIdSet(String paasPermissionsStr) {
        Set<Long> paasAppPerm = new HashSet<>();
        List<AppPermissionPojo> appPerms;
        try {
            appPerms = JSON.parseArray(paasPermissionsStr, AppPermissionPojo.class);
        } catch (Exception e) {
            LOG.error("checkPermission paasPermissions数据不规范" + paasPermissionsStr, e);
            appPerms = new ArrayList<>();
        }
        if (appPerms != null) {
            for (AppPermissionPojo appPerm : appPerms) {
                paasAppPerm.add(appPerm.getAppId());
            }
        }
        return paasAppPerm;
    }

    /**
     * 获取当前登录人对特定paas表单的操作权限
     *
     * @param loginUser 当前登录人信息
     * @param appId     应用id
     * @param menuId    菜单id
     * @return 当前登录人对特定paas表单的操作权限
     */
    public static PermissionTermsPojo getPaasFormPermission(UserVO loginUser, Long appId, Long menuId) {
        if (loginUser.isAdminOrBoss()) {
            return new PermissionTermsPojo(true);
        }
        return getPaasFormPermission(loginUser.getPaasPermissions(), appId, menuId);
    }

    /**
     * 通过已有 permissionTerms 和员工/角色paas权限计算对应该 appId 该 menuId 对应的最大 permissionTerms 权限
     * 执行完成后，最大权限会复写在 permissionTerms 中
     *
     * @param permissionTerms 上次计算后的PermissionTermsPojo
     * @param paasPermissions 员工/角色paas权限
     * @param appId           permissionTerms对应的appId
     * @param menuId          permissionTerms对应的menuId
     */
    public static void getMaxPermissionTerms(PermissionTermsPojo permissionTerms, String paasPermissions, Long appId, Long menuId) {
        /*
        计算本permissionTerms 和 getPaasFormPermission(paasPermissions, appId, menuId)) 的最大权限
        并用最大权限覆盖本permissionTerms
         */
        permissionTerms.maxPermission(getPaasFormPermission(paasPermissions, appId, menuId));
    }

    /**
     * 通过DTO中userLogin参数的paasPermissions字段 或 roleEntity的paasPermissions字段，
     * 获得通过appId和menuId指定的paas模块表单的权限实体PermissionTermsPojo
     *
     * @param paasPermissions 登录用户的paas表单权限 或 某角色具有的paas表单权限
     * @param appId           应用id
     * @param menuId          菜单id
     * @return 对应paas模块的权限实体PermissionTermsPojo
     */
    private static PermissionTermsPojo getPaasFormPermission(String paasPermissions, Long appId, Long menuId) {
        // 默认权限
        PermissionTermsPojo permission = new PermissionTermsPojo();
        // 解析appPermissionPojo
        List<AppPermissionPojo> appPermissions = JSON.parseArray(paasPermissions, AppPermissionPojo.class);
        if (appPermissions == null || appPermissions.size() == 0) {
            return permission;
        }

        // 找到对应的appPermissionPojo
        AppPermissionPojo thisApp = null;
        for (AppPermissionPojo enableApp : appPermissions) {
            if (Objects.nonNull(enableApp) && Objects.equals(appId, enableApp.getAppId())) {
                thisApp = enableApp;
                break;
            }
        }
        if (thisApp == null || thisApp.getModules() == null) {
            return permission;
        }

        for (ModulePermissionPojo modulePermission : thisApp.getModules()) {
            if (menuId.equals(modulePermission.getId())) {
                permission = modulePermission.getPermission();
                break;
            }
        }
        return permission;
    }
}
